package com.tianji.promotion;

import com.google.common.collect.Lists;
import lombok.Data;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

public class LocalCacheAndConcurrent {

    @Data
    public class ShopInfo {

        private Integer id;
        private String name;
        private String address;
    }

    public class ShopService {
        public Map<Integer, String> getShopName(List<Integer> shopIds) {
            return Collections.emptyMap();
        }

        public Map<Integer, String> getShopAddress(List<Integer> shopIds) {
            return Collections.emptyMap();
        }
    }

    public class AService {
        private ShopService shopService = new ShopService();

        /*
         * 根据商户id批量查询商户信息，入参shopIds不大于100个
         * 1、并行调用shopService提供的getShopName和getShopAddress方法获取商户名称和地址，构造ShopInfo
         * 2、从ShopService获取数据时，需要满足ShopService入参不大于10个。需要分批调用
         * 3、优先从本地缓存中获取数据，本地缓存没有再从ShopService查询
         * */
        public Map<Integer, ShopInfo> getShopInfo(List<Integer> shopIds) {
            // 分为多个小集合
            List<List<Integer>> list = Lists.partition(shopIds, 10);
            Map<Integer, ShopInfo> shopInfoMap = new HashMap<>();
            // 每次处理一个小集合
            for (List<Integer> ids : list) {
                // 已存在不再继续查询
                ids.forEach(id -> {
                    if (shopInfoMap.containsKey(id)) {
                        ids.remove(id);
                    }
                });

                Map<Integer, String> shopName = shopService.getShopName(ids);
                Map<Integer, String> shopAddress = shopService.getShopAddress(ids);
                ShopInfo shopInfo = new ShopInfo();
                List<ShopInfo> infos = new ArrayList<>();

                // 对象属性赋值
                ids.forEach(c -> {
                    shopInfo.setId(c);
                    shopInfo.setName(shopName.get(c));
                    shopInfo.setAddress(shopAddress.get(c));
                    infos.add(shopInfo);
                });
                shopInfoMap.putAll(infos.stream().collect(Collectors.toMap(ShopInfo::getId, Function.identity())));
            }
            return shopInfoMap;
        }
    }


    /**
     * @param originalPrice       原价(未扣除优惠前的价格)
     * @param finalPrice          到手价(扣除所有优惠后的价格，即用户需要实际支付的金额)
     * @param historicalPriceList 历史到手价列表
     */
    public static String computeProductPromoTag(BigDecimal originalPrice, BigDecimal finalPrice, List<BigDecimal> historicalPriceList) {
        //历史最低
        BigDecimal min = historicalPriceList.stream().min(BigDecimal::compareTo).get();
        // 三月最低
        BigDecimal minOfThreeMonth = new BigDecimal(0);
        //  historicalPriceList.stream().filter
        // 通过月份限定近三月并获取最低价，题目中没有月份条件这里 mock一下

        // 如果是历史最低，则输出："历史最低"
        if (finalPrice.compareTo(min) <= 0) {
            return "历史最低";
        }
        // 如果是近3个月最低，则输出："近3月最低"
        if (finalPrice.compareTo(minOfThreeMonth) <= 0) {
            return "近3月最低";
        }
        // 如果有折扣(折扣要大于0.1且小于9.9,小数点向下取),则输出："xx扣",小数点最多保留1位(向下取),如最后一位小数是0则删除
        BigDecimal discount = finalPrice.setScale(1, BigDecimal.ROUND_DOWN);
        boolean isDiscount = discount.compareTo(BigDecimal.ONE) > 0 && discount.compareTo(new BigDecimal("9.9")) < 0;
        if (isDiscount) {
            discount = originalPrice.subtract(finalPrice).divide(originalPrice, 2, BigDecimal.ROUND_DOWN);
            String discountString = discount.stripTrailingZeros().toPlainString();
            if (discountString.endsWith(".0")) {
                discountString = discountString.substring(0, discountString.length() - 2);
            }
            return discountString + "折扣";
        }
        // 兜底文案，输出“到手价”
        return "到手价";
    }

}
